package com.example.wechat;

import com.example.wechat.util.HttpClientUtil;
import com.example.wechat.util.SignUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.Signer;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.*;
import java.util.Base64;

@Controller
@Slf4j
public class PayController {
    private static final Logger logger = LoggerFactory.getLogger(PayController.class);

    @RequestMapping("/token")
    public String token(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("=={}=={}==",request, request.getParameter("signature"));
        logger.info("=={}==code={}==",request, request.getParameter("code"));
        if (StringUtils.isNotBlank(request.getParameter("signature"))) {
            String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echostr = request.getParameter("echostr");
            logger.info("signature[{}], timestamp[{}], nonce[{}], echostr[{}]", signature, timestamp, nonce, echostr);
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                logger.info("数据源为微信后台，将echostr[{}]返回！", echostr);
                response.getOutputStream().println(echostr);
            }
            return echostr;
        }
        return request.getParameter("echostr");
    }

//    @RequestMapping("/placeOrder")
//    public ModelAndView placeOrder(HttpServletRequest request, HttpServletResponse response) throws IOException {
//        logger.info("==placeOrder==={}=={}==",request, request.getParameter("signature"));
//        logger.info("==placeOrder==={}==code={}==",request, request.getParameter("code"));
//        ModelAndView modelAndView = new ModelAndView();
//        modelAndView.setViewName("index.html");
//        return modelAndView;
//    }


    @RequestMapping("/placeOrder")
    public void placeOrder(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect("https://www.baidu.com");
    }

    @RequestMapping("/getCode")
    public String getCode(HttpServletRequest request, Model model) throws IOException {
        logger.info("=={}==code={}==",request, request.getParameter("code"));
        if (StringUtils.isNotBlank(request.getParameter("code"))) {
            String json = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxfe37ddbe2dde921b&secret=a84f85878279493501374648d1a53bf1&code=" + request.getParameter("code") + "&grant_type=authorization_code");
            JSONObject jsonObject = JSONObject.fromObject(json);
            String openid = jsonObject.getString("openid");
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                    new FileInputStream("/work/apiclient_key.pem"));
            CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                    .withMerchant("1632010016", "7756CC99D32B941BAA8D2EF42401E98F28C35EF6", merchantPrivateKey)
                    .withValidator(response -> true) // NOTE: 设置一个空的应答签名验证器，**不要**用在业务请求
                    .build();
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-type","application/json; charset=utf-8");

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectMapper objectMapper = new ObjectMapper();

            ObjectNode rootNode = objectMapper.createObjectNode();
            rootNode.put("mchid","1632010016")
                    .put("appid", "wxfe37ddbe2dde921b")
                    .put("description", "入群")
                    .put("notify_url", "http://yxdy.xzydzx.cn/placeOrder")
                    .put("out_trade_no", generateNonceStr());
            rootNode.putObject("amount")
                    .put("total", 1);
            rootNode.putObject("payer")
                    .put("openid", openid);

//        ocQRd5ifG8c6EFqGB_ung8Q_U2yw
            objectMapper.writeValue(bos, rootNode);

            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
            CloseableHttpResponse response = httpClient.execute(httpPost);

            String bodyAsString = EntityUtils.toString(response.getEntity());
            logger.info("=========={}", bodyAsString);
            JSONObject prepayIdjsonObject = JSONObject.fromObject(bodyAsString);
            PrivateKey privateKey = PemUtil.loadPrivateKey(
                    new FileInputStream("/work/apiclient_key.pem"));

            long l = System.currentTimeMillis() / 1000;
            String nonceStr = generateNonceStr();
            String prepayId = prepayIdjsonObject.getString("prepay_id");
            model.addAttribute("l", l);
            model.addAttribute("nonceStr", nonceStr);
            model.addAttribute("prepayId", "prepay_id=" + prepayId);


            String message = "wxfe37ddbe2dde921b\n" + l + "\n" + nonceStr + "\nprepay_id=" + prepayId + "\n";

            try {
                Signature sign = Signature.getInstance("SHA256withRSA");
                sign.initSign(privateKey);
                sign.update(message.getBytes());
                Signer.SignatureResult signatureResult = new Signer.SignatureResult(Base64.getEncoder().encodeToString(sign.sign()), "7756CC99D32B941BAA8D2EF42401E98F28C35EF6");
                model.addAttribute("sign", signatureResult.getSign());
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
            } catch (SignatureException e) {
                throw new RuntimeException("签名计算失败", e);
            } catch (InvalidKeyException e) {
                throw new RuntimeException("无效的私钥", e);
            }
        }

        model.addAttribute("key", 12345);
        return "test.html";
    }

//    @RequestMapping("/pay")
//    public String pay(String openId) throws IOException {

//        return bodyAsString;
//    }
    protected static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    protected static final SecureRandom RANDOM = new SecureRandom();
    protected String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }
    public static void main(String[] args) throws IOException {
//        String s = HttpClientUtil.doGet("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxfe37ddbe2dde921b&redirect_uri=http%3A%2F%2Fyxdy.xzydzx.cn%2Ftoken&response_type=code&scope=snsapi_base&state=123#wechat_redirect");
//        System.out.println(s);
//        String s = HttpClientUtil.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxfe37ddbe2dde921b&secret=a84f85878279493501374648d1a53bf1");
//        System.out.println(s);
        String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxfe37ddbe2dde921b&secret=a84f85878279493501374648d1a53bf1&code=091SwDFa1WSY9E0iR2Ga1WeCCg4SwDF8&grant_type=authorization_code");
        System.out.println(s);
//        System.out.println(URLDecoder.decode("http://yxdy.xzydzx.cn/token","utf-8"));
//        System.out.println(URLEncoder.encode("http://yxdy.xzydzx.cn/token","utf-8"));

//        System.out.println(URLEncoder.encode("http://yxdy.xzydzx.cn/1.txt"));

        String json = "{\"access_token\":\"62_pA_p7cEjpLdQ88F53VNOQ97RvLRCz0D9yVijXgwJF0EA1cX9RuGqbTa1x1XyFOguE_ck9iu1MJZ_hnh9cikBuWCwl2gKvb4qndAFL_UU978\",\"expires_in\":7200,\"refresh_token\":\"62_y2Gn1XlWeSk375-SnNahVzi5hbpB8hqsFBegYk2jBRO1HyVc5OwW8kgQPJwVn5B6igbZGmI32HeL4fqHXt8FndtwC76UAPONkis9k3yCFuo\",\"openid\":\"ocQRd5ifG8c6EFqGB_ung8Q_U2yw\",\"scope\":\"snsapi_base\"}\n";

        JSONObject jsonObject = JSONObject.fromObject(json);
        System.out.println(jsonObject.getString("openid"));
    }
}
